package com.znjc.device.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.znjc.common.constant.DeviceConstants;
import com.znjc.device.domain.*;
import com.znjc.device.domain.vo.IotData;
import com.znjc.device.domain.vo.TdengineQueryVO;
import com.znjc.device.mapper.*;
import com.znjc.device.service.DeviceDataService;
import com.znjc.device.websocket.WebSocketUsers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DeviceDataServiceImpl extends ServiceImpl<TDeviceDataMapper, DeviceData> implements DeviceDataService {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Resource
    HlDataMapper hlDataMapper;
    @Resource
    CxDataMapper cxDataMapper;
    @Resource
    TdzhbDataMapper tdzhbDataMapper;
    @Resource
    NbqDataMapper nbqDataMapper;
    @Resource
    IotDataMapper iotDataMapper;

    @Override
    public boolean saveBatch(Collection<DeviceData> entityList) {
        List<List<DeviceData>> groupList = new ArrayList<>();
        entityList.stream().collect(Collectors.groupingBy(DeviceData::getDeviceId, Collectors.toList()))
                .forEach((model, list) -> {
                    groupList.add(list);
                });
        if (CollectionUtils.isNotEmpty(groupList)) {
            groupList.stream().forEach(objList -> {
                if (CollectionUtils.isNotEmpty(objList)) {
                    IotData data = new IotData();
                    DeviceDevice device = objList.get(0).getDevice();
                    data.setTs(objList.get(0).getTs());
                    data.setAddress(objList.get(0).getAddress());
                    data.setDeviceId(device.getId());
                    objList.stream().forEach(entity -> {
                        if (null != entity.getPoint()) {
                            data.setDeviceId(entity.getDeviceId());
                            data.setDeviceName(entity.getDeviceName());
                            data.setPointId(entity.getPointId());
                            data.setDataType(device.getXsdx());
                            data.setAlarmType(entity.getAlarmType());
                            if ("电阻".equals(entity.getPoint().getPointName())) {
                                data.setDz(entity.getActualValue());
                                data.setDzUnit(entity.getDataUnit());
                            } else if ("电压".equals(entity.getPoint().getPointName())) {
                                data.setDy(entity.getActualValue());
                                data.setDyUnit(entity.getDataUnit());
                            } else if ("电流".equals(entity.getPoint().getPointName())) {
                                data.setDl(entity.getActualValue());
                                data.setDlUnit(entity.getDataUnit());
                            } else if ("频率".equals(entity.getPoint().getPointName())) {
                                data.setPl(entity.getActualValue());
                                data.setPlUnit(entity.getDataUnit());
                            }
                        }
                    });
                    if ("1".equals(device.getXsdx())) {
                        BigDecimal dzj = new BigDecimal("10");
                        if (null != device.getDzj()) {
                            dzj = device.getDzj();
                        }
                        String dzl = new BigDecimal("2").multiply(new BigDecimal("3.14").multiply(dzj).multiply(new BigDecimal(data.getDz())).divide(new BigDecimal("1000"))).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
                        data.setDzl(dzl);
                    }
                    iotDataMapper.insert(data);
                    redisTemplate.opsForValue().set(DeviceConstants.TABLE_NAME + data.getDeviceId() + "_" + data.getAddress(), JSONObject.toJSONString(data));
                    WebSocketUsers.sendMessageToUserByText(DeviceConstants.VUE_MSG_CLINET_9999, "采集完成");
                    WebSocketUsers.sendMessageToUserByText(DeviceConstants.VUE_MSG_CLINET_9998, JSONObject.toJSONString(data));
                    /*if (data.getAddress().replaceAll("_", " ").equals(DeviceConstants.SD_CODE)) {
                        DeviceConstants.SD_FLAG = true;
                        log.info(DeviceConstants.SD_CODE + "测量完成");
                    }*/
                }
            });
        }
        return true;
    }

    /**
     * 逆变器
     *
     * @param entity
     */
    @Override
    public void saveNbq(NbqData entity) {
        if (null != entity) {
            nbqDataMapper.insert(entity);
            redisTemplate.opsForValue().set(DeviceConstants.NBQ, JSONObject.toJSONString(entity));
        }
    }

    /**
     * 保存通道转换板
     *
     * @param entity
     */
    @Override
    public void saveTdzhb(TdzhbData entity) {
        if (null != entity) {
            tdzhbDataMapper.insert(entity);
            redisTemplate.opsForValue().set(DeviceConstants.TDZHB, JSONObject.toJSONString(entity));
        }
    }

    /**
     * 保存磁芯电流
     *
     * @param entity
     */
    @Override
    public void saveCx(CxData entity) {
        if (null != entity) {
            cxDataMapper.insert(entity);
            redisTemplate.opsForValue().set(DeviceConstants.CX, JSONObject.toJSONString(entity));
            WebSocketUsers.sendMessageToUserByText(DeviceConstants.VUE_MSG_CLINET_9998, JSONObject.toJSONString(entity));
        }
    }

    /**
     * 保存回流电流
     *
     * @param entity
     */
    @Override
    public void saveHl(HlData entity) {
        if (null != entity) {
            hlDataMapper.insert(entity);
            redisTemplate.opsForValue().set(DeviceConstants.HL, JSONObject.toJSONString(entity));
            WebSocketUsers.sendMessageToUserByText(DeviceConstants.VUE_MSG_CLINET_9998, JSONObject.toJSONString(entity));
        }
    }

    @Override
    public List<IotData> getListIotData(TdengineQueryVO queryVO) {
        LambdaQueryWrapper<IotData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(IotData::getDeviceId, queryVO.getDeviceId());
        wrapper.orderByDesc(IotData::getTs);
        return iotDataMapper.selectList(wrapper);
    }

    @Override
    public List<IotData> getListIotData(LambdaQueryWrapper<IotData> wrapper) {
        return iotDataMapper.selectList(wrapper);
    }

    @Override
    public List<IotData> selectTrendData(List<Long> deviceIds, List<Long> pointIds, Date startTime, Date endTime, String dataType) {
        LambdaQueryWrapper<IotData> wrapper = new LambdaQueryWrapper<>();
        if(CollectionUtils.isNotEmpty(deviceIds)){
            wrapper.in(IotData::getDeviceId, deviceIds);
        }
        if(CollectionUtils.isNotEmpty(pointIds)){
            wrapper.in(IotData::getPointId, pointIds);
        }
        if(startTime != null){
            wrapper.ge(IotData::getTs, startTime);
        }
        if(endTime != null){
            wrapper.le(IotData::getTs, endTime);
        }
        if(dataType != null){
            wrapper.eq(IotData::getDataType, dataType);
        }
        wrapper.orderByDesc(IotData::getTs);
        return iotDataMapper.selectList(wrapper);
    }

    @Override
    public Boolean saveDeviceDatas(List<DeviceData> deviceDatas) {
        if(CollectionUtils.isNotEmpty(deviceDatas)){
            deviceDatas.forEach(deviceData -> {
                getBaseMapper().insert(deviceData);
            });
        }
        return true;
    }

}
